package com.smedi.ismedi.authoritymanagement.core.domain.service.impl;

import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.FrameStructure;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RolePermissionDetail;
import com.smedi.ismedi.authoritymanagement.core.domain.repository.FrameStructureRepository;
import com.smedi.ismedi.authoritymanagement.core.domain.repository.RolePermissionDetailRepository;
import com.smedi.ismedi.authoritymanagement.core.domain.service.FrameStructureDomainService;
import com.smedi.ismedi.authoritymanagement.core.domain.service.RolePermissionDetailDomainService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: xulinjun
 * @Date: 2021-8-17 14:15
 */
@Slf4j
@Service
@AllArgsConstructor
public class RolePermissionDetailDomainServiceImpl implements RolePermissionDetailDomainService {
    private final RolePermissionDetailRepository rolePermissionDetailRepository;
    private final FrameStructureRepository frameStructureRepository;
    private final FrameStructureDomainService frameStructureDomainService;

    @Override
    public List<Long> getScopeStructureIdsByRootCodeAndRoleId(String rootCode, Long roleId) {
        List<Long> list = new ArrayList<>();
        List<RolePermissionDetail> rolePermissionDetails = rolePermissionDetailRepository.selectAllByRootCodeAndRoleId(rootCode, roleId);
        List<FrameStructure> children = frameStructureRepository.selectAllChildren();
        rolePermissionDetails.stream().forEach(rolePermissionDetail -> {
            if (rolePermissionDetail.isAllChildren()) {
                list.add(rolePermissionDetail.getStructureId()); // 添加自身

                list.addAll(frameStructureDomainService.queryAllChildrenByStructureId(rolePermissionDetail.getStructureId(), children)
                        .stream()
                        .map(FrameStructure::getStructureId)
                        .collect(Collectors.toList()));
            } else {
                list.add(rolePermissionDetail.getStructureId());
            }
        });

        return list.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public List<Long> getScopeStructureIdsByRootCodeAndRoleIds(String rootCode, List<Long> roleIds,List<FrameStructure> children) {
        List<Long> list = new ArrayList<>();
        List<RolePermissionDetail> rolePermissionDetails = rolePermissionDetailRepository.selectAllByRootCodeAndRoleIds(rootCode, roleIds);

        rolePermissionDetails.stream().forEach(rolePermissionDetail -> {
            if (rolePermissionDetail.isAllChildren()) {
                list.add(rolePermissionDetail.getStructureId()); // 添加自身

                list.addAll(frameStructureDomainService.queryAllChildrenByStructureId(rolePermissionDetail.getStructureId(),children)
                        .stream()
                        .map(FrameStructure::getStructureId)
                        .collect(Collectors.toList()));
            } else {
                list.add(rolePermissionDetail.getStructureId());
            }
        });
        return list.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public void cleanCurrentPermissionsByRootCodeAndRoleId(String rootCode, Long roleId) {
        rolePermissionDetailRepository.deleteAllByRootCodeAndRoleId(rootCode, roleId);
    }

    @Override
    public void batchSaveRolePermissionDetail(String rootCode, Long roleId, List<RolePermissionDetail> rolePermissionDetails, boolean cleanCurrent) {
        if (cleanCurrent) {
            cleanCurrentPermissionsByRootCodeAndRoleId(rootCode, roleId);
        }

        rolePermissionDetails.stream().forEach(rolePermissionDetail -> {
            rolePermissionDetail.setRoleId(roleId);
            rolePermissionDetailRepository.doInsert(rolePermissionDetail);
        });
    }

    @Override
    public List<RolePermissionDetail> getRolePermissionDetailsByRootCodeAndRoleId(String rootCode, Long roleId) {
        return rolePermissionDetailRepository.selectAllByRootCodeAndRoleId(rootCode, roleId);
    }
}
